"""
    Copyright (C) 2009  Andrew Stanton

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

"""
from xml.sax.saxutils import XMLGenerator
from xml.sax.xmlreader import AttributesNSImpl
import cStringIO

class XMLMarshaller(object):
    
    @staticmethod
    def dump(value, file):
        # Build root document
        xmldoc = XMLGenerator(file)
        xmldoc.startDocument()
        attrs = AttributesNSImpl({},{})
        xmldoc.startElementNS((None, u'root'), u'root', attrs)
        
        # Render recursively
        XMLMarshaller.renderXML(value, xmldoc)
        xmldoc.endElementNS((None, u'root'), u'root')
        xmldoc.endDocument()
        return file

    @staticmethod
    def dumps(value):
        file = cStringIO.StringIO()
        return XMLMarshaller.dump(value, file).getvalue()

    @staticmethod
    def renderXML(obj, doc):
        '''
        Renders out a dictionary-like object as an xml file.
        '''
        attrs = AttributesNSImpl({},{})

        # Assumes it's a dictionary
        if hasattr(obj, 'iteritems'):
            for k,v in obj.iteritems():
                if not isinstance(v, list):
                    v = [v]
                for i in v:
                    doc.startElementNS((None, k), k, attrs)
                    XMLMarshaller.renderXML(i, doc)
                    doc.endElementNS((None, k), k)

        # Assumes it's a list
        elif hasattr(obj, '__iter__'):
            for item in obj:
                
                XMLMarshaller.renderXML(item, doc)

        # Basic type?
        else:
            doc.characters(unicode(obj))
